package info.niwota.ziplock;

import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore.Images.Media;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class ZipContentProvider extends ContentProvider {

	public static final Uri CONTENT_URI = Uri
			.parse("content://info.niwota.ziplock.zip");

	public static final String AUTHORITY = "info.niwota.ziplock.zip";

	private static final UriMatcher URI_MATCHER;

	public static final String[] COL_NAMES = new String[] { Media._ID,
			Media.DATA, Media.DATE_TAKEN, Media.MINI_THUMB_MAGIC,
			Media.ORIENTATION, Media.TITLE, Media.MIME_TYPE,
			Media.DATE_MODIFIED };

	private static final int ZIPFILE = 1;

	private static final String TAG = "ZipContentProvider";

	static {
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(AUTHORITY, "", ZIPFILE);
		URI_MATCHER.addURI(AUTHORITY, "/", ZIPFILE);
		URI_MATCHER.addURI(AUTHORITY, "/*", ZIPFILE);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String getType(Uri uri) {
		return "vnd.android.cursor.item/ziplock.file";
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean onCreate() {
		return true;
	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {
		return 0;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		if (Debug.DEBUG) {
			Log.d(TAG, "query: "
					+ uri
					+ " projection: "
					+ (projection == null ? "" : Arrays.asList(projection))
					+ " selection: "
					+ selection
					+ " args: "
					+ (selectionArgs == null ? "" : Arrays
							.asList(selectionArgs)) + " sortOrder: "
					+ sortOrder);
		}

		// int type = URI_MATCHER.match(uri);
		// if (type == UriMatcher.NO_MATCH) {
		// return null;
		// }

		try {
			MatrixCursor c = new MyMatrixCursor(uri);
			c.setNotificationUri(getContext().getContentResolver(), uri);
			return c;
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		throw new UnsupportedOperationException();
	}

	private class MyMatrixCursor extends MatrixCursor {
		private Uri uri;

		public MyMatrixCursor(Uri uri) throws Exception {
			super(COL_NAMES);
			this.uri = uri;
			//
			load();
		}

		protected void load() throws Exception {
			Context ctx = getContext();
			String path = uri.getPath();
			File file = new File(path);
			// top: /root/cache/zip/path/bame/
			String zipname = file.getName();
			File top = new File(FileContentProvider.ROOT, zipname);

			ArchiveFile arc = new ArchiveFile(ctx, top, file,
					FileContentProvider.FILE_EXT);
			
			long start = System.currentTimeMillis();
			if (Debug.DEBUG) {
				Log.d(TAG, "start listing... ");
			}
			
			List<FileItem> list = arc.list();
			
			long end = System.currentTimeMillis();
			if (Debug.DEBUG) {
				Log.d(TAG, "done listing " + ((end - start) / 1000));
			}
			
			int size = list.size();
			rowCount = 0;
			data = new Object[size * columnCount];
			int idx = 0;
			
			Uri base = FileContentProvider.constructBaseUri(zipname);
			
			for (Iterator<FileItem> i = list.iterator(); i.hasNext();) {
				FileItem fi = i.next();
				String p = fi.getName();
				//
				Uri u = Uri.withAppendedPath(base, p);

				if (Debug.DEBUG) {
					Log.d(TAG, "u: " + u);
				}
				long modified = fi.getModified();
				//
				// {
				// Media._ID,
				// Media.DATA, Media.DATE_TAKEN, Media.MINI_THUMB_MAGIC,
				// Media.ORIENTATION, Media.TITLE, Media.MIME_TYPE,
				// Media.DATE_MODIFIED
				// }
				Object[] row = new Object[] { idx++, u, modified, 0, 0, p, "",
						modified };
				//
				addRow(row);
			}
		}

		@Override
		public boolean requery() {
			if (Debug.DEBUG) {
				Log.d(TAG, "requerying...");
			}
			try {
				load();
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			return super.requery();
		}
	}

}
